home *** CD-ROM | disk | FTP | other *** search
- /*
- * This file contains procedures to process a symbol file.
- *
- * The following operations are required:
- *
- * Open a symbol file.
- * Scan through the segments in a symbol file.
- * For a given segment scan through the symbols.
- * For each symbol, store the symbol value in an array.
- */
- #include <stdio.h>
- #include <process.h>
- #include <string.h>
- #include <malloc.h>
- #include <dgb.h>
- #include <exc.h>
- #include "types.h"
- #include "symfile.h"
- #include "segments.h"
- #include "profile.h"
-
- SYMHDR SFheader;
- SYMSEG SFseg;
- PNSTR ModuleName = NULL;
-
- PSTR FileName;
- FILE *CurrentSymbolFile = NULL;
- WORD LastPara = 0;
-
- void CloseSymbolFile()
- {
- if (CurrentSymbolFile != NULL)
- {
- fclose (CurrentSymbolFile);
- CurrentSymbolFile = NULL;
- if (ModuleName != NULL)
- {
- free((char *)ModuleName);
- ModuleName = NULL;
- }
- FileName = NULL;
- }
- }
-
- /*
- * Open a symbol file. Path searching has already been done.
- */
- FILE *OpenSymFile (name)
- PSTR name;
- {
- if (CurrentSymbolFile != NULL) CloseSymbolFile();
- FileName = name;
- CurrentSymbolFile = fopen(name, "rb");
- if (CurrentSymbolFile == NULL)
- {
- BadFile = name; exc_raise(OP_FAILED);
- }
- fread ((char *)&SFheader, sizeof(SYMHDR), 1, CurrentSymbolFile);
- ModuleName = ReadName();
- return CurrentSymbolFile;
- }
-
- BOOL IsSymFileName(name)
- PSTR name;
- {
- WORD l = strlen(name);
- if (l > 4 && strcmpi(name+l-4, ".SYM") == 0) return TRUE;
- return FALSE;
- }
-
- WORD RdWord ()
- {
- WORD w;
- fread ((char *)&w, 2, 1, CurrentSymbolFile);
- return w;
- }
-
- void LoadSymFile (name)
- PSTR name;
- {
- WORD seg;
- WORD i;
- OpenSymFile (name);
- fprintf(stderr, "Reading '%s'... %d segment%s\n", name, SFheader.Nsegs, (SFheader.Nsegs == 1?"":"s"));
- seg = SFheader.FirstSeg;
- for (i = 0; i < SFheader.Nsegs; i++)
- {
- seg = LoadSegment (seg);
- }
- CloseSymbolFile();
- }
-
- PNSTR ReadName()
- {
- BYTE l = (BYTE) getc (CurrentSymbolFile);
- PNSTR n = (PNSTR) emalloc (sizeof(NSTR) + l);
- n->len = l;
- fread (n->s, l, 1, CurrentSymbolFile);
- n->s[l] = 0;
- return n;
- }
-
- void SkipName()
- {
- BYTE l = (BYTE) getc (CurrentSymbolFile);
- fseek (CurrentSymbolFile, (long) l, SEEK_CUR);
- }
-
-
- WORD LoadSegment(offset)
- WORD offset;
- {
- PNSTR SegName;
- PPD ProcDesc;
- WORD vsize;
- WORD i;
- PSEGMENT ps;
- fseek (CurrentSymbolFile, offset * 16L, SEEK_SET);
- fread ((char *) &SFseg, sizeof(SYMSEG), 1, CurrentSymbolFile);
- SegName = ReadName();
- fprintf(stderr, "Segment %s!%s %d symbol%s\n", ModuleName->s, SegName->s, SFseg.Nsyms, (SFseg.Nsyms==1?"":"s"));
- vsize = sizeof (VALBLOCK) * (SFseg.Nsyms-1) + sizeof(PD);
-
- ProcDesc = (PPD) emalloc (vsize);
-
- ProcDesc->filename = FileName;
- ProcDesc->segname = SegName;
- ProcDesc->len = SFseg.Nsyms;
- for (i = 0; i < SFseg.Nsyms; i++)
- {
- ProcDesc->vals[i].label = RdWord();
- ProcDesc->vals[i].count = 0;
- SkipName();
- }
- /* Now install this segment in my list... */
- ps = (PSEGMENT) DefineSegment ((LPSTR) ModuleName->s, SFseg.Ordinal-1, 0, 0, 0);
- if (ps != NULL) ps->Procs = ProcDesc;
- return SFseg.ParaNext;
- }
-
- /*
- * This code is used for output to translate the addresses into symbols.
- * To keep it simple, it only runs well if it is called for increasing addresses.
- * This should be the normal case.
- */
- WORD OldOrdinal = 0;
- WORD OldOffset = 0;
- WORD SymsLeft = 0;
-
- static PNSTR SearchForSymbol (WORD);
- static BOOL SearchForSegment (WORD);
- static WORD LoadSegHdr (WORD);
-
- PNSTR FindSymbol (file, SegOrdinal, Offset)
- PSTR file;
- WORD SegOrdinal;
- WORD Offset;
- {
- /*printf("Looking in %s for %04x:%04x\n", file, SegOrdinal, Offset);*/
- if (file == FileName && SegOrdinal == OldOrdinal && Offset > OldOffset)
- return SearchForSymbol (Offset);
-
- OldOrdinal = SegOrdinal;
- OldOffset = Offset;
- if (file != FileName) OpenSymFile (file);
- unless (SearchForSegment (SegOrdinal)) return NULL;
- SearchForSymbol (Offset);
- }
-
- /* Opened correct file, found the right segment. Now just search for the symbol. */
- static PNSTR SearchForSymbol (Offset)
- WORD Offset;
- {
- while (SymsLeft > 0)
- {
- WORD label = RdWord();
- /*printf(" %04x", label);*/
- if (label == Offset)
- {
- return ReadName();
- }
- SkipName();
- SymsLeft--;
- if (label > Offset) return NULL;
- }
- return NULL;
- }
-
- static BOOL SearchForSegment (SegOrd)
- WORD SegOrd;
- {
- WORD seg = SFheader.FirstSeg;
- WORD i;
- for (i = 0; i < SFheader.Nsegs; i++)
- {
- seg = LoadSegHdr (seg);
- /*printf("Looking at segment %d\n", SFseg.Ordinal);*/
- if (SFseg.Ordinal == SegOrd)
- {
- SymsLeft = SFseg.Nsyms;
- return TRUE;
- }
- }
- return FALSE;
- }
-
- static WORD LoadSegHdr (offset)
- WORD offset;
- {
- fseek (CurrentSymbolFile, offset * 16L, SEEK_SET);
- fread ((char *) &SFseg, sizeof(SYMSEG), 1, CurrentSymbolFile);
- SkipName(); /* Dont want segment name this time */
- return SFseg.ParaNext;
- }
-